package com.tcl.aota.admin.controller;

import com.tcl.aota.admin.dto.*;
import com.tcl.aota.admin.manager.AppManager;
import com.tcl.aota.admin.util.FileStoreUtil;
import com.tcl.aota.admin.util.RequestUtil;
import com.tcl.aota.common.constants.Constants;
import com.tcl.aota.common.utils.IPUtil;
import com.tcl.aota.manage.AppManage;
import com.tcl.aota.manage.CurefManage;
import com.tcl.aota.manage.PackageManage;
import com.tcl.aota.persistent.model.Admin;
import com.tcl.aota.persistent.model.App;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class AppController {

    private static Logger logger = Logger.getLogger(AppManager.class);
    @Resource(name = "appManage")
    private AppManage appManage;

    @Resource(name = "packageManage")
    private PackageManage packageManage;

    @Resource(name = "appManager")
    private AppManager appManager;

    @Resource(name = "curefManage")
    private CurefManage curefManage;


    @ResponseBody
    @RequestMapping(value = "/app/recycle/remove", method = RequestMethod.POST)
    public Result removerFromRecycle(@RequestBody List<Long> ids) {
        return Result.get(Constants.Common.NULL, appManager.deleteApps(ids));
    }

    @ResponseBody
    @RequestMapping(value = "/app/recycle/recovery", method = RequestMethod.POST)
    public Result recoveryFromTrash(@RequestBody List<Long> ids) {
        return Result.get(Constants.Common.NULL, appManage.putOutRecycle(ids));
    }

    /**
     * app list by query condition
     *
     * @param appParam
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/list/{pageNo}", method = RequestMethod.POST)
    public Result getAppList(@RequestBody AppParamDTO appParam,
                             @PathVariable Integer pageNo) {
        Map<String, Object> paramMap = appParam.putCondsMap();
        paramMap.put("start", (pageNo - 1) * Constants.Common.PAGE_SIZE);
        paramMap.put("pageSize", Constants.Common.PAGE_SIZE);
        int total = appManage.selectAppCountByConds(paramMap);
        List<App> appList = appManage.selectAppListByConds(paramMap);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("appList", appList);
        resultMap.put("total", total);
        resultMap.put("pageSize", Constants.Common.PAGE_SIZE);
        resultMap.put("pageNo", pageNo);
        return Result.get(resultMap, Constants.Common.SUCCESS);
    }

    /**
     * add app
     *
     * @param appVo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/add", method = RequestMethod.POST)
    public Result add(@RequestBody AppVo appVo, HttpServletRequest request) {
        return Result.get(Constants.Common.NULL, appManager.insertApp(appVo, request));
    }


    /**
     * app detail by appId
     *
     * @param appId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/detail/{appId}", method = RequestMethod.GET)
    public Result detail(@PathVariable Long appId) {
        return Result.get(appManage.selectByIdFromDb(appId), Constants.Common.SUCCESS);
    }

    /**
     * update app
     *
     * @param appDTO
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/update", method = RequestMethod.POST)
    public Result update(@RequestBody AppVo appDTO) {
        return Result.get(Constants.Common.NULL, appManager.updateApp(appDTO));
    }

    /**
     * batch del apps
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/del", method = RequestMethod.POST)
    public Result del(@RequestBody List<Long> ids,HttpServletRequest request) {
        String ip = IPUtil.getIpAddr(request);
        Admin admin = RequestUtil.getSessionUser(request);
        return Result.get(Constants.Common.NULL, appManage.putInRecycle(ids, ip, admin.getAdminName()));
    }

    /**
     * update app by sequence.
     *
     * @param appId
     * @param sequence
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/sequence/{appId}/{sequence}", method = RequestMethod.POST)
    public Result updateBySequence(@PathVariable Long appId,
                                   @PathVariable Integer sequence) {
        return Result.get(Constants.Common.NULL,
            appManage.updateAppBySeq(appId, sequence));
    }

    /**
     * parse the apk and get app info
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/parseApk")
    public Result parseApk(HttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile apkFile = multipartRequest.getFile("apkFile");
        String uuid = FileStoreUtil.storeAPk(apkFile);
        return Result.get(appManager.parseApk(uuid, request), Constants.Common.SUCCESS);
    }

    /**
     * upload the file to the tmp dir /tmp/aota-store/ and return the uuid.
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/uploadIcon", method = RequestMethod.POST)
    public Result uploadIcon(HttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile multipartFile = multipartRequest.getFile("iconFile");
        FileReponseDTO reponseDTO = new FileReponseDTO();
        reponseDTO.setFileName(multipartFile.getOriginalFilename());
        String uuid = FileStoreUtil.storeImg(multipartFile);
        if (uuid == null) {
            reponseDTO.fail();
        } else {
            reponseDTO.setFileUuid(uuid);//上传成功
            //sync upload the img to s3
            appManager.synFile(uuid, Constants.APK.ICON_FLAG);
        }
        return Result.get(reponseDTO, Constants.Common.SUCCESS);
    }


    @ResponseBody
    @RequestMapping(value = "/app/res/uploadImg", method = RequestMethod.POST)
    public Result uploadImg(HttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile multipartFile = multipartRequest.getFile("imgFile");
        FileReponseDTO reponseDTO = new FileReponseDTO();
        reponseDTO.setFileName(multipartFile.getOriginalFilename());
        String uuid = FileStoreUtil.storeImg(multipartFile);
        if (uuid == null) {
            reponseDTO.fail();
        } else {
            reponseDTO.setFileUuid(uuid);//上传成功
            //sync upload the img to s3
            appManager.synFile(uuid, Constants.APK.IMAGS_FLAG);
        }
        return Result.get(reponseDTO, Constants.Common.SUCCESS);
    }

    /**
     * upload the file to the tmp dir /tmp/aota-store/ and return the uuid.
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/app/res/upload", method = RequestMethod.POST)
    public Result upload(HttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> filesMap = multipartRequest.getFileMap();
        List<FileReponseDTO> reponseDTOs = new ArrayList<FileReponseDTO>();
        if (filesMap != null) {
            for (Map.Entry<String, MultipartFile> entry : filesMap.entrySet()) {
                MultipartFile multipartFile = entry.getValue();
                FileReponseDTO result = new FileReponseDTO();
                result.setFileName(multipartFile.getOriginalFilename());
                String uuid = FileStoreUtil.storeImg(multipartFile);
                if (uuid == null) {
                    result.fail();
                } else {
                    result.setFileUuid(uuid);
                }
                reponseDTOs.add(result);
            }
        }
        return Result.get(reponseDTOs, Constants.Common.SUCCESS);
    }

    /**
     * publish app to curef
     *
     * @return
     */
    @RequestMapping(value = "/app/publish")
    @ResponseBody
    public Result publish(@RequestBody CurefParam curefParam,HttpServletRequest request) {
        return appManager.publishApp(curefParam,request);
    }

    /**
     * unpubilsh apps
     *
     * @param appIds
     * @return
     */
    @RequestMapping(value = "/app/unPublish")
    @ResponseBody
    public Result unPublish(@RequestBody List<Long> appIds,HttpServletRequest request) {
        return appManager.unPublishApp(appIds,request);
    }

    /**
     * get curefs by appId
     *
     * @param appId
     * @return
     */
    @RequestMapping(value = "/app/curefs/{appId}", method = RequestMethod.GET)
    @ResponseBody
    public Result curefs(@PathVariable Long appId) {
        return appManager.appCuref(appId);
    }

    /**
     * 删除已发布CU
     *
     * @param curefs
     * @return
     */
    @RequestMapping(value = "/app/curefs/del/{appId}", method = RequestMethod.POST)
    @ResponseBody
    public Result appCurefDel(@PathVariable Long appId, @RequestBody List<String> curefs, HttpServletRequest request) {
        String ip = IPUtil.getIpAddr(request);
        Admin admin = RequestUtil.getSessionUser(request);
        return Result.get(null, appManage.deleteAppCurefByAppIdAndCus(appId, curefs, ip, admin.getAdminName()));
    }

    /**
     * parse the apk and get app info
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/thirdApi/uploadApk")
    public JsonResult uploadApkApi(HttpServletRequest request, @RequestParam(value = "appKey", required = true) String appKey) {
        return appManager.thirdUploadApk(request, appKey);
    }
}
